import { useState, useEffect, useContext, memo, useCallback, useRef } from 'react'
import { useRequest } from 'alova/client'
import { useShallow } from 'zustand/react/shallow'
import { toast } from 'sonner'
import { BadgeCheckIcon, PlayCircle, PauseCircle } from 'lucide-react'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Progress } from '@/components/ui/progress'
import { Badge } from '@/components/ui/badge'
import { saveBlobFile } from '@/lib/downloadFile'
import { getMusicUrlMethod, downloadMusicMethod, downloadPictureMethod } from '@/apis/music'
import {
  musicStore,
  useDownloadQualityStore,
  useDownloadMusicMethodStore,
  usePlayMusicMethodStore,
  useDownloadProviderStore,
} from '@/stores/music-stores'

import type { MusicStoreRecord } from '@/types/music'
import type { BaseParams, DownloadMusicParams } from '@/apis/music'

const DownloadedMusicList = (): JSX.Element => {

  // 下载列表：首次渲染从数据库中获取
  const [downloadedMusicList, setDownloadMusicList] = useState<MusicStoreRecord[]>([])
  const [currentDownloadMusic, setCurrentDownloadMusic] = useState<MusicStoreRecord | null>(null)

  const quality = useDownloadQualityStore(state => state.downloadQuality)
  const provider = useDownloadProviderStore(state => state.downloadProvider)
  const setDownloadMusicMethod = useDownloadMusicMethodStore(state => state.setDownloadMusicMethod)
  const handlePlayMusic = usePlayMusicMethodStore(state => state.playMusicMethod)

  // const musicPlayerContext = useContext(MusicPlayerContext)

  useEffect(() => {
    console.info('[render Component]:%c DownloadedMusicList', 'color: red;', Date.now())
  })

  useEffect(() => {
    // 暴露下载方法
    setDownloadMusicMethod(handleDownloadMusic)
    // 获取已下载音乐列表
    musicStore.getMusicList().then((data) => {
      setDownloadMusicList(data)
    })
    return () => {
      setDownloadMusicMethod(null)
      setCurrentDownloadMusic(null)
    }
  }, [])

  const getMusicUrlRequest = useRequest(getMusicUrlMethod, { initialData: {}, immediate: false, })

  const getLyricRequest = useRequest(getMusicUrlMethod, { initialData: {}, immediate: false, })

  const getPictureUrlRequest = useRequest(getMusicUrlMethod, { initialData: {}, immediate: false, })

  const downloadMusicRequest = useRequest(downloadMusicMethod, { initialData: undefined, immediate: false, })

  const downloadPictureRquest = useRequest(downloadPictureMethod, { initialData: undefined, immediate: false, })

  const handleDownloadMusic = async (
    musicInfo: MusicStoreRecord, quality: string, provider: string, type?: 'music' | 'cover' | 'lyric'
  ): Promise<void> => {
    downloadMusic(musicInfo, quality, provider)
    // const hasDownloaded = downloadedMusicList.find((item) => item.id === musicInfo.id)
    // if (hasDownloaded) {
    //   let continueDownload = false
    //   if (!type) {
    //     toast.warning(`${musicInfo.artist?.join(' / ')}-${musicInfo.name}已经在下载列表中，是否重新下载？`, {
    //       action: { label: '确定', onClick: () => { continueDownload = true } },
    //       cancel: { label: '取消', onClick: () => { continueDownload = false } }
    //     })
    //   } else if (type === 'music' && hasDownloaded.music_blob_list?.[quality]) {
    //     toast.warning(`该歌曲曾经下载过，是否重新下载？`, {
    //       action: { label: '确定', onClick: () => { continueDownload = true } },
    //       cancel: { label: '取消', onClick: () => { continueDownload = false } }
    //     })
    //   } else if (type === 'lyric' && hasDownloaded.lyric) {
    //     toast.warning(`该歌词曾经下载过，是否重新下载？`, {
    //       action: { label: '确定', onClick: () => { continueDownload = true } },
    //       cancel: { label: '取消', onClick: () => { continueDownload = false } }
    //     })
    //   } else if (type === 'cover' && hasDownloaded.cover_blob) {
    //     toast.warning(`该图片曾经下载过，是否重新下载？`, {
    //       action: { label: '确定', onClick: () => { continueDownload = true } },
    //       cancel: { label: '取消', onClick: () => { continueDownload = false } }
    //     })
    //   } else {
    //     continueDownload = true
    //   }
    //   if (!continueDownload) return
    // } else {
    //   setCurrentDownloadMusic(musicInfo)
    //   setDownloadMusicList((prevData) => {
    //     const newData = [musicInfo].concat(prevData.filter((item) => item.id !== musicInfo.id))
    //     return newData
    //   })
    // }
    // let singleRequestMusicStoreItem: MusicStoreRecord | undefined = undefined
    // if (!type) {
    //   setCurrentDownloadMusic(musicInfo)
    //   Promise.allSettled([
    //     downloadMusic({ id, source, quality, musicInfo }),
    //     downloadLyric(lyric_id, musicInfo),
    //     downloadPicture(pic_id, musicInfo)
    //   ]).then((promisesResult) => {
    //     const [downloadMusicRes, downloadLyricRes, downloadPictureRes] = promisesResult as { status: string, value: object }[]
    //     const musicStoreItem = {
    //       ...musicInfo,
    //       ...(downloadMusicRes.value || {}),
    //       ...(downloadLyricRes.value || {}),
    //       ...(downloadPictureRes.value || {})
    //     }
    //     console.log('musicStoreItem', musicStoreItem)
    //     setDownloadMusicList((prevData) => {
    //       const purePrevData = prevData.filter((item) => item.id !== musicInfo.id)
    //       purePrevData.push(musicStoreItem)
    //       return purePrevData.reverse()
    //     })
    //     saveDownloadedMusic(musicStoreItem)
    //     setCurrentDownloadMusic(null)
    //   })
    // } else {
    //   try {
    //     if (type === 'music') {
    //       const downloadMusicRes = await downloadMusic(url_id, musicInfo) || {}
    //       singleRequestMusicStoreItem = { ...musicInfo, ...downloadMusicRes, }
    //     } else if (type === 'lyric') {
    //       const downloadLyricRes = await downloadLyric(lyric_id, musicInfo) || {}
    //       singleRequestMusicStoreItem = { ...musicInfo, ...downloadLyricRes, }
    //     } else if (type === 'pic') {
    //       const downloadPictureRes = await downloadPicture(pic_id, musicInfo) || {}
    //       singleRequestMusicStoreItem = { ...musicInfo, ...downloadPictureRes, }
    //     }
    //     if (singleRequestMusicStoreItem) {
    //       const cloneSingleRequestMusicStoreItem = structuredClone(singleRequestMusicStoreItem)
    //       setDownloadMusicList((prev) => [
    //         cloneSingleRequestMusicStoreItem,
    //         ...(prev.filter(Boolean).filter((item) => item.id !== cloneSingleRequestMusicStoreItem.id))
    //       ])
    //       await saveDownloadedMusic(singleRequestMusicStoreItem)
    //     }
    //   } finally {
    //     setCurrentDownloadMusic(null)
    //   }
    // }
  }

  /**
   * 下载音乐本体
   * @param id 音乐id、不是返回的列表的id，是 url_id
   */
  const downloadMusic = async (musicInfo: MusicStoreRecord, quality: string, provider: string): Promise<{
    musicBlob: Blob,
    musicUrl: string,
  } | undefined> => {
    let toasterId: string | number = ''
    console.log('musicInfo', musicInfo)
    try {
      if (!musicInfo.source) {
        toast.error('下载歌曲失败：无效的歌曲来源')
        return
      }
      if (!musicInfo.id) {
        toast.error('下载歌曲失败：无效的歌曲id')
        return
      }
      if (!quality) {
        toast.error('下载歌曲失败：无效的音质')
        return
      }
      toasterId = toast.loading('正在获取歌曲下载链接...')
      const {
        code: getMusicUrlResponseCode,
        url: musicUrl,
      }: {
        code: number,
        url: string,
      } = await getMusicUrlRequest.send({
        id: musicInfo.id, source: musicInfo.source, quality, provider
      }) || {}
      if (!musicUrl || !(getMusicUrlResponseCode == 200)) {
        toast.error('获取歌曲链接失败，请重试', { id: toasterId })
        return
      }
      toast.loading('获取歌曲链接成功，开始下载...', { id: toasterId })
      const musicBlob: Blob = await downloadMusicRequest.send({
        url: musicUrl, musicInfo, quality, provider
      })
      const fileName = `${musicInfo.artist?.join('_') || '未知艺术家'}-${musicInfo.name}.${musicUrl.split('.').pop()}`
      if (!Object.prototype.toString.call(musicBlob).includes('Blob')) {
        toast.error(`【${fileName}】下载失败：链接错误！`, { id: toasterId })
        return
      }
      const saveSuccess = await saveBlobFile(musicBlob, fileName)
      if (!saveSuccess) {
        toast.error(`【${fileName}】保存失败：文件转换失败`, { id: toasterId, })
        return
      }
      toast.success(`【${fileName}】下载成功`, { id: toasterId })
      musicInfo.music_blob_list = musicInfo.music_blob_list || {}
      musicInfo.music_blob_list[quality] = musicBlob
      await musicStore.saveMusic(musicInfo)
      return { musicBlob, musicUrl }
    } catch (err) {
      toast.error(`下载失败：${(err as Error).message}`, { id: toasterId || '' })
      return
    }
  }

  /**
   * 下载歌词
   * @param id 歌词id 歌词ID即lyric_id（一般与曲目ID相同）
   */
  // const downloadLyric = async (id: number | string, musicItem: MusicStoreRecord): Promise<{
  //   lyric: string
  //   tlyric: string
  // } | undefined> => {
  //   let toasterId: string | number = ''
  //   try {
  //     if (!id) {
  //       toast.error('下载歌词失败：无效的歌词id')
  //       return
  //     }
  //     toasterId = toast.loading('正在获取歌词...')
  //     const lyric: MusicLyricRecord = await getLyricRequest.send({
  //       types: 'lyric',
  //       source: musicItem.source || '',
  //       id: String(id),
  //     })
  //     if (!getLyricResponse || !getLyricResponse.lyric) {
  //       toast.error('获取歌词失败:：歌词为空', { id: toasterId })
  //       return
  //     }
  //     toast.loading('获取歌词成功，开始下载...', { id: toasterId })
  //     const { lyric, tlyric } = getLyricResponse
  //     const lyricBlob = new Blob([lyric], { type: 'text/plain;charset=utf-8' })
  //     const fileName = `${musicItem.artist.join('_')}-${musicItem.name}.lrc`
  //     const saveSuccess = await saveBlobFile(lyricBlob, fileName)
  //     if (!saveSuccess) {
  //       toast.error(`【${fileName}】保存失败：文件转换失败`, { id: toasterId, })
  //       return
  //     }
  //     toast.success(`【${fileName}】下载成功`, { id: toasterId })
  //     return {
  //       lyric,
  //       tlyric,
  //     }
  //   } catch (err) {
  //     toast.error(`下载失败：${(err as Error).message}`, { id: toasterId || '' })
  //     return
  //   }
  // }

  /**
   * 下载歌曲专辑封面
   * @param id 专辑图id 即pic_id
   * @returns
   */
  // const downloadPicture = async (id: number | string, musicItem: MusicStoreRecord): Promise<{
  //   pic_url: string
  //   picBlob: Blob
  // } | undefined> => {
  //   let toasterId: string | number = ''
  //   try {
  //     if (!id) {
  //       toast.error('下载专辑封面失败：无效的封面id')
  //       return
  //     }
  //     toasterId = toast.loading('正在获取专辑封面下载链接...')
  //     const getPictureUrlResponse: MusicPictureRecord = await getPictureUrlRequest.send({
  //       types: 'pic',
  //       source: musicItem.source || '',
  //       id: String(id),
  //       size: 500, // 图片大小 300 | 500 数字不表示图片实际大小，只表示图片质量
  //     })
  //     if (!getPictureUrlResponse || !getPictureUrlResponse.url) {
  //       toast.error('获取专辑封面链接失败:：url为空', { id: toasterId })
  //       return
  //     }
  //     const { url } = getPictureUrlResponse
  //     toast.loading('获取专辑封面链接成功，开始下载...', { id: toasterId })
  //     const picBlob: Blob = await downloadPictureRquest.send(url, musicItem)
  //     const fileName = `${musicItem.artist.join('_')}-${musicItem.name}.${url.split('?')[0].split('.').pop()}`
  //     if (!Object.prototype.toString.call(picBlob).includes('Blob')) {
  //       toast.error(`【${fileName}】下载失败：链接错误！`, { id: toasterId })
  //       return
  //     }
  //     const saveSuccess = await saveBlobFile(picBlob, fileName)
  //     if (!saveSuccess) {
  //       toast.error(`【${fileName}】保存失败：文件转换失败`, { id: toasterId, })
  //       return
  //     }
  //     toast.success(`【${fileName}】下载成功`, { id: toasterId })
  //     return {
  //       pic_url: url,
  //       picBlob,
  //     }
  //   } catch (err) {
  //     toast.error(`下载失败：${(err as Error).message}`, { id: toasterId || '' })
  //     return
  //   }
  // }

  const computedDownloadItemProgress = (musicItem: MusicStoreRecord): number => {
    if (currentDownloadMusic?.id === musicItem.id && !musicItem.music_blob_list?.[quality]) {
      return downloadMusicRequest.downloading.loaded / downloadMusicRequest.downloading.total * 100
    } else if (musicItem.music_blob_list?.[quality]) {
      return 100
    } else {
      return 0
    }
  }

  return <ScrollArea className='download-list music-list-scroll-area'>
    {
      downloadedMusicList.filter(Boolean).map(musicItem => {
        return <div className='download-music-item' key={musicItem.id}>
          <div className='flex justify-between pb-2'>
            <div className='text-sm text-gray-700'>{musicItem.artist?.join('/')} - {musicItem.name}</div>
          </div>
          <div className='flex items-center'>
            <PlayCircle className='pr-1' size={'1.5em'} onClick={() => { handlePlayMusic(musicItem.id, musicItem.source, quality) }} />
            <Progress value={computedDownloadItemProgress(musicItem)} />
          </div>
          <div className='download-info'>
            {musicItem.music_blob_list?.[quality] ? <Badge
              variant="secondary"
              className="downloaded-success"
            >
              <BadgeCheckIcon />歌曲
            </Badge> : <Badge
              variant="outline"
              className='undownload'
                onClick={() => handleDownloadMusic(musicItem, quality, provider, 'music')}
            >
              <BadgeCheckIcon />歌曲
            </Badge>}
            {musicItem.cover_blob ? <Badge
              variant="secondary"
              className="downloaded-success"
            >
              <BadgeCheckIcon />封面
            </Badge> : <Badge
              variant="outline"
              className='undownload'
              onClick={() => handleDownloadMusic(musicItem, quality, provider, 'cover')}
            >
              <BadgeCheckIcon />封面
            </Badge>}
            {musicItem.lyric ? <Badge
              variant="secondary"
              className="downloaded-success"
            >
              <BadgeCheckIcon />歌词
            </Badge> : <Badge
              variant="outline"
              className='undownload'
              onClick={() => handleDownloadMusic(musicItem, quality, provider, 'lyric')}
            >
              <BadgeCheckIcon />歌词
            </Badge>}
          </div>
        </div>
      })
    }
  </ScrollArea>
}

export default DownloadedMusicList
